#include "web_service.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>

#include "civetweb/CivetServer.h"
#include "civetweb_handler.h"
#include "httpserver/httpserver.h"
#include "websocketserver/websocketserver.h"



/***************************************************************
 * 功能：构造函数
* *************************************************************/
WebService::WebService()
    : m_spCivetSrv(nullptr)
{

}

/***************************************************************
 * 功能：析构函数
 * *************************************************************/
WebService::~WebService()
{
    stop();
}

/***************************************************************
 * 功能：初始化civetweb库，只需要在网络通信开始之前调用一次
 * *************************************************************/
void WebService::initLib()
{
    initCivetWebLib();
    return;
}

/***************************************************************
 * 功能：反初始化civetweb库，只需要在网络通信结束之后调用一次
 * *************************************************************/
void WebService::deinitLib()
{
    deinitCivetWebLib();
    return;
}

/***************************************************************
 * 功能：开始服务
 * 输入参数：
 *      usPort：服务端口
 * *************************************************************/
void WebService::start(unsigned short usPort)
{
    if (!m_bRunning) {
        m_usSrvPort = usPort;
        std::vector<std::string> vtOptions;
        vtOptions.clear();

        vtOptions.push_back("document_root");
        vtOptions.push_back("/doc_root/");
        vtOptions.push_back("listening_ports");
        vtOptions.push_back(std::to_string(m_usSrvPort));
        vtOptions.push_back("websocket_timeout_ms");
        vtOptions.push_back("5000");
        vtOptions.push_back("request_timeout_ms");
        vtOptions.push_back("5000");
        vtOptions.push_back("enable_keep_alive");
        vtOptions.push_back("yes");
        vtOptions.push_back("tcp_nodelay");
        vtOptions.push_back("1");
        vtOptions.push_back("keep_alive_timeout_ms");
        vtOptions.push_back("5000");
        vtOptions.push_back("num_threads");
        vtOptions.push_back("4");

        m_spCivetSrv = std::make_shared<CivetServer>(vtOptions);
        if (m_spCivetSrv) {
            // 注意：各服务句柄不能使用局部变量
            auto spWsHandler1 = std::make_shared<Example1WebsocketHandler>();
            if (spWsHandler1) {
                m_spCivetSrv->addWebSocketHandler(spWsHandler1->getUrl(), spWsHandler1.get());
                m_vtWsHandlers.emplace_back(spWsHandler1);
            }

            auto spWsHandler2 = std::make_shared<Example2WebsocketHandler>();
            if (spWsHandler2) {
                m_spCivetSrv->addWebSocketHandler(spWsHandler2->getUrl(), spWsHandler2.get());
                m_vtWsHandlers.emplace_back(spWsHandler2);
            }

            auto spHttpHandler1 = std::make_shared<Example1HttpServerHandler>();
            if (spHttpHandler1) {
                m_spCivetSrv->addHandler(spHttpHandler1->getUrl(), spHttpHandler1.get());
                m_vtHttpHandlers.emplace_back(spHttpHandler1);
            }

            m_bRunning = true;
            printf(">>> web server is started on port: %d.\r\n", m_usSrvPort);
        } else {
            m_bRunning = false;
            printf(">>> new CivetServer instance failed!\r\n");
        }

    } else {
        printf(">>> please call stop first!\r\n");
    }

    return;
}

/***************************************************************
 * 功能：停止服务
 * *************************************************************/
void WebService::stop()
{
    if (m_spCivetSrv) {
        for (auto& spHandler : m_vtWsHandlers) {
            if (spHandler.get()) {
                m_spCivetSrv->removeWebSocketHandler(spHandler->getUrl());
                spHandler.reset();
            }
        }
        m_vtWsHandlers.clear();

        for (auto& spHandler : m_vtHttpHandlers) {
            if (spHandler.get()) {
                m_spCivetSrv->removeHandler(spHandler->getUrl());
                spHandler.reset();
            }
        }
        m_vtHttpHandlers.clear();


        m_spCivetSrv->close();
        m_spCivetSrv.reset();
        m_spCivetSrv = nullptr;
        printf(">>> web server is stoped on port: %d.\r\n", m_usSrvPort);
    }

    m_bRunning = false;

    return;
}

/***************************************************************
 * 功能：获取服务状态
 * 返回值：
 *      bool：运行状态，true -- 运行中，false -- 停止运行
 * *************************************************************/
bool WebService::isRunning() const
{
    return m_bRunning;
}

/***************************************************************
 * 功能：获取服务端口信息
 * 返回值：
 *      unsigned int：服务端口信息
 * *************************************************************/
unsigned int WebService::getSrvPort() const
{
    return m_usSrvPort;
}

